libobs_wrapper\data\output/
replay_buffer.rs1use std::{
7 path::{Path, PathBuf},
8 sync::Arc,
9};
10
11use crate::{
12 data::{
13 object::ObsObjectTrait,
14 output::{ObsOutputRef, ObsOutputTraitSealed},
15 },
16 forward_obs_object_impl, forward_obs_output_impl, impl_signal_manager, run_with_obs,
17 runtime::ObsRuntime,
18 unsafe_send::{Sendable, SmartPointerSendable},
19 utils::{ObsCalldataExt, ObsError, ObsString, OutputInfo},
20};
21
22#[derive(Debug, Clone)]
23pub struct ObsReplayBufferOutputRef {
31 replay_signal_manager: Arc<ObsReplayOutputSignals>,
33
34 output: ObsOutputRef,
35}
36
37impl ObsOutputTraitSealed for ObsReplayBufferOutputRef {
38 fn new(mut output: OutputInfo, runtime: ObsRuntime) -> Result<Self, ObsError> {
39 output.id = ObsString::new("replay_buffer");
40 let output = ObsOutputRef::new(output, runtime.clone())?;
41
42 let replay_signal_manager = ObsReplayOutputSignals::new(&output.as_ptr(), runtime)?;
43 Ok(Self {
44 replay_signal_manager: Arc::new(replay_signal_manager),
45 output,
46 })
47 }
48}
49
50forward_obs_object_impl!(ObsReplayBufferOutputRef, output, *mut libobs::obs_output);
51forward_obs_output_impl!(ObsReplayBufferOutputRef, output);
52
53impl_signal_manager!(|ptr: SmartPointerSendable<*mut libobs::obs_output>| {
54 unsafe {
55 libobs::obs_output_get_signal_handler(ptr.get_ptr())
57 }
58}, ObsReplayOutputSignals for *mut libobs::obs_output, [
59 "saved": {}
60]);
61
62impl ObsReplayBufferOutputRef {
63 pub fn replay_signals(&self) -> &Arc<ObsReplayOutputSignals> {
64 &self.replay_signal_manager
65 }
66 pub fn save_buffer(&self) -> Result<Box<Path>, ObsError> {
83 log::trace!("Saving replay buffer...");
84 let output_ptr = self.as_ptr();
85
86 log::trace!("Getting procedure handler for replay buffer output...");
87 let proc_handler = run_with_obs!(self.runtime().clone(), (output_ptr), move || {
88 let ph = unsafe { libobs::obs_output_get_proc_handler(output_ptr.get_ptr()) };
90 if ph.is_null() {
91 return Err(ObsError::OutputSaveBufferFailure(
92 "Failed to get proc handler.".to_string(),
93 ));
94 }
95 Ok(Sendable(ph))
96 })??;
97
98 log::trace!("Calling 'save' procedure on replay buffer output...");
99 unsafe { self.runtime().call_proc_handler(&proc_handler, "save")? };
101
102 log::trace!("Waiting for 'saved' signal from replay buffer output...");
103 self.replay_signals()
104 .on_saved()?
105 .blocking_recv()
106 .map_err(|_e| {
107 ObsError::OutputSaveBufferFailure(
108 "Failed to receive saved replay buffer path.".to_string(),
109 )
110 })?;
111
112 log::trace!("Retrieving last replay path from replay buffer output...");
113 let mut calldata = unsafe {
115 self.runtime()
116 .call_proc_handler(&proc_handler, "get_last_replay")?
117 };
118
119 log::trace!("Extracting path from calldata...");
120 let path = calldata.get_string("path")?;
121 let path = PathBuf::from(path);
122
123 Ok(path.into_boxed_path())
124 }
125}